home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1994 August: Tool Chest / Dev.CD Aug 94.toast / New System Software Extensions / PlainTalk™ Speech Technologies / Text to Speech / Programming Stuff / Examples / SpeakFile / BigEasy.c next >
Encoding:
C/C++ Source or Header  |  1993-09-15  |  23.4 KB  |  917 lines  |  [TEXT/KAHL]

  1. /*
  2.     File:        BigEasy.c
  3.  
  4.     Contains:    Main Event Loop Processing
  5.  
  6.     Written by:    David Van Brink & The Utility Muffin Research Kitchen
  7.  
  8.     Copyright:    © 1991-1992 by Apple Computer, Inc., all rights reserved.
  9.  
  10.     Change History (most recent first):
  11.  
  12.          <9>     4/20/92    JDR        Changed the sleep timeout for WaitNextEvent to always be a
  13.                                     standard time, because we'll poll faster when we're trying to
  14.                                     play a sound using a FakeInterrupt method which waits for events
  15.                                     using OSEventAvail.
  16.          <8>     2/26/92    JDR        Doing a little clean up. Changed some menus around.
  17.          <7>     2/16/92    JDR        Conditional for the Think C MacHeaders or MPW's MacHeaders. Got
  18.                                     rid of warnings. Needed to add #pragmas to the default routines.
  19.          <6>     1/16/92    JDR        Using MacHeaders instead of all those includes to make builds go
  20.                                     faster.
  21.          <5>     12/4/91    JDR        Keep sleeping at zero, for now.
  22.          <4>    11/15/91    JDR        Changed the event loop to call idle procs and added a global
  23.                                     sleep parameter.
  24.          <3>    10/16/91    JDR        Changing NewWindow to NewCWindow, added a new GetxxxWindow call,
  25.                                     and had to change the event handlers a bit
  26.          <2>     9/27/91    KIP        Fix DoClose to correctly dispose of all windows in the window
  27.                                     object list.
  28.          <1>     9/27/91    KIP        Change DoQuit to dispose every window in the list.
  29.     To Do:
  30. */
  31.  
  32. #ifdef THINK_C
  33.     #include <MacHeaders>
  34. #else
  35.     #pragma load "MPWHeaders"
  36. #endif
  37.  
  38. #define LoMemGrayRgn    (* (RgnHandle*) GrayRgn)        /* gray region */
  39. #define    LoMemWMgrPort    (* (GrafPtr*) WMgrPort)            /* WMgrPort */
  40. #define    LoMemROM85        (* (unsigned short*) ROM85)        /* ROM version */
  41. #define    HaveCQD()        (LoMemROM85 <= 0x3FFF)            /* true if color quickdraw is present */
  42.  
  43. #include "BigEasy.h"
  44. //#include "SndManager.h"
  45.  
  46. //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  47. // Limits
  48. //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  49.  
  50. #define WMax 30            /* Number of windows in list */
  51. #define MMax 15            /* Number of menus in menubar */
  52. #define MIMax 48        /* Number of items per menu */
  53.  
  54. Rect bigRect = {-16000,-16000,16000,16000};
  55.  
  56. //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  57. // Types
  58. //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  59.  
  60. /*** Windows ***/
  61. typedef struct                /* This clever little structure contains */
  62. {                            /* pointers to routines for each type of event. */
  63.     UpdateProc        wUpdate;
  64.     ClickProc        wClick;
  65.     GrowProc        wGrow;
  66.     KeyProc            wKey;
  67.     CloseProc        wClose;
  68.     DeathProc        wDeath;
  69.     ActivateProc    wActivate;
  70.     DeactivateProc    wDeactivate;
  71.     LoopyProc        wLoopy;
  72.     WindowPtr        wWindow;
  73.     Ptr                wGlobals;
  74. } WindowObject, *WindowObjectPtr;
  75.  
  76. //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  77. // Globals
  78. //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  79.  
  80. WindowObject WindowObjectList[WMax];    /* Maximum of 30 controlled windows */
  81. short WindowCount = 0;                    /* Number of windows defined */
  82.  
  83. /*** Menus ***/
  84. MenuHandle MenuHandleList[MMax];        /* MenuHandles indexed by MenuID's */
  85. IFP MenuProcs[MMax][MIMax];                /* Array of procedures to call from menus */
  86. short MenuCount;                            /* How many menus defined */
  87. short MenuItemCount;                        /* How many items in last menu */
  88. MenuHandle MenuEdit;                    /* Which one is the edit menu? */
  89.  
  90. /*** Application Edit Commands ***/
  91. IFP AppUndo,AppCut,AppCopy,AppPaste,AppClear;
  92.  
  93. /*** Global Status ***/
  94. Boolean gQuitApp = false;
  95. long    gLastMenuSelect = 0;
  96.  
  97.  
  98. //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  99. // prototypes
  100. //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  101.  
  102. void            InitToolbox(void);
  103. void            DoMyAbout(void);
  104. void            BEUndo(void);
  105. void            BECut(void);
  106. void            BECopy(void);
  107. void            BEPaste(void);
  108. void            BEClear(void);
  109. void            BENull(void);
  110. void            DefaultUpdate(Ptr globals);
  111. void            DefaultClick(Ptr globals, Point p, short mods, long when);
  112. void            DefaultGrow(Ptr globals, Point p, short mods);
  113. void            DefaultKey(Ptr globals, long k, short mods);
  114. void            DefaultClose(Ptr globals);
  115. void            DefaultDeath(Ptr globals);
  116. void            DefaultActivate(Ptr globals);
  117. void            DefaultDeactivate(Ptr globals);
  118. void            DefaultLoopy(Ptr globals);
  119. void            pnull(void);
  120. void            MenuPoint(long theclick);
  121. void            DoKeyPress(long k);
  122. void            MenuClick(Point p);
  123. void            StartMenus(void);
  124. void            InstallMenu(Str255 s);
  125. void            InstallItem(Str255 s, IFP action);
  126. void            InstallEditMenu(IFP Xundo, IFP Xcut, IFP Xcopy, IFP Xpaste, IFP Xclear);
  127. void            EnableMenu(MenuHandle menu, short item, Boolean enable);
  128. void            EnDis(MenuHandle m, short i, short f);
  129. void            EnDisEdits(short Eundo, short Ecut, short Ecopy, short Epaste, short Eclear);
  130. void            DoMouseClick(EventRecord *event);
  131. void            DoGrowWindow(WindowPtr window, EventRecord *event);
  132. void            DoZoomWindow(WindowPtr window, short part);
  133. void            ResizeWindow(WindowPtr window);
  134. void            GetLocalUpdateRgn(WindowPtr window, RgnHandle localRgn);
  135. Ptr                InstallWindow(Rect *iRect, short iType, Boolean iGoway, unsigned char *iTitle, UpdateProc iUpdate, ClickProc iClick, GrowProc iGrow, KeyProc iKey, CloseProc iClose, DeathProc iDeath, ActivateProc iActivate, DeactivateProc iDeactive, LoopyProc iLoopy, long iGlobalsSize, WindowPtr *thisWindowPtr);
  136. Ptr                GetInstallWindow(short windID, UpdateProc iUpdate, ClickProc iClick, GrowProc iGrow, KeyProc iKey, CloseProc iClose, DeathProc iDeath, ActivateProc iActivate, DeactivateProc iDeactive, LoopyProc iLoopy, long iGlobalsSize, WindowPtr *thisWindowPtr);
  137. Ptr                InstallDialog(short iResID, ClickProc iClick, CloseProc iClose, long iGlobalsSize, DialogPtr *thisWindowPtr);
  138. void            UninstallWindow(WindowPtr uWindow);
  139. void            UninstallDialog(DialogPtr uDialog);
  140. void            DoCloseWindow(void);
  141. void            DoQuit(void);
  142. WindowObjectPtr    ScanWindowObjectList(WindowPtr w, short *n);
  143. Ptr                GetWindowStorage(WindowPtr w);
  144. void            FrontDA(void);
  145. GrafPtr            SaveGrafPort(GrafPtr newPort);
  146. void            EventLoop(void);
  147. void            DoNew(void);
  148. void            DoOpen(void);
  149. void            DoClose(Ptr storage);
  150. void            main(void);
  151.  
  152.  
  153. /************************************
  154. * Some useful routines
  155. ************************************/
  156.  
  157. //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  158. void InitToolbox(void)
  159.   {
  160.   InitGraf(&qd.thePort);
  161.   InitFonts();
  162.   FlushEvents(0xffff,0);
  163.   InitWindows();
  164.   InitMenus();
  165.   InitDialogs(0);
  166.   TEInit();
  167.   InitCursor();
  168.   }
  169.  
  170. void CopyStr(Str255 source, Str255 dest)
  171. {
  172.     BlockMove(source, dest, source[0]+1);
  173. }
  174.  
  175. void AppendStr(Str255 source, Str255 dest)
  176. {
  177.     BlockMove(&source[1], &dest[dest[0]+1], source[0]);
  178.     dest[0] += source[0];
  179. }
  180.  
  181. void TrapError(Str255 s, OSErr err, Boolean breakIt, Boolean fatal)
  182. {
  183.     short            i;
  184.     WindowObjectPtr    wo;
  185.  
  186.     if (err)
  187.     {
  188.         if (breakIt)
  189.         {
  190.             Str255     errStr;
  191.             Str31    numStr;
  192.         
  193.             CopyStr(s, errStr);
  194.             AppendStr("\p: ", errStr);
  195.             NumToString(err, numStr);
  196.             if ((numStr[0] + errStr[0]) > 255)
  197.                 numStr[0] = 255 - errStr[0];
  198.             AppendStr(numStr, errStr);
  199.             
  200.             DebugStr(errStr);
  201.         }
  202.         
  203.         if (fatal) 
  204.         {
  205.             wo = WindowObjectList;
  206.             i = WindowCount;
  207.             while (i--)
  208.                 (*wo->wDeath)(wo->wGlobals);
  209.             
  210.             ExitToShell();
  211.         }
  212.     }
  213. }
  214.  
  215. //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  216. void DoMyAbout(void)
  217.   {
  218.   SysBeep(1);
  219.   }
  220.  
  221.  
  222. /************************************
  223. * Some inherent methods
  224. ************************************/
  225.  
  226. //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  227. void BEUndo(void)
  228.   {
  229.   if(!SystemEdit(0))
  230.     (*AppUndo)();
  231.   }
  232.  
  233. //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  234. void BECut(void)
  235.   {
  236.   if(!SystemEdit(2))
  237.     (*AppCut)();
  238.   }
  239.  
  240. //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  241. void BECopy(void)
  242.   {
  243.   if(!SystemEdit(3))
  244.     (*AppCopy)();
  245.   }
  246.  
  247. //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  248. void BEPaste(void)
  249.   {
  250.   if(!SystemEdit(4))
  251.     (*AppPaste)();
  252.   }
  253.  
  254. //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  255. void BEClear(void)
  256.   {
  257.   if(!SystemEdit(5))
  258.     (*AppClear)();
  259.   }
  260.  
  261. //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  262. // default routines
  263.  
  264. void BENull(void){}
  265. void DefaultUpdate(Ptr globals)
  266. {
  267. #pragma unused (globals)
  268. }
  269. void DefaultClick(Ptr globals, Point p, short mods, long when)
  270. {
  271. #pragma unused (globals, p, mods, when)
  272. }
  273. void DefaultGrow(Ptr globals, Point p, short mods)
  274. {
  275. #pragma unused (globals, p, mods)
  276. }
  277. void DefaultKey(Ptr globals, long k, short mods)
  278. {
  279. #pragma unused (globals, k, mods)
  280. }
  281. void DefaultClose(Ptr globals)
  282. {
  283. #pragma unused (globals)
  284. }
  285. void DefaultDeath(Ptr globals)
  286. {
  287. #pragma unused (globals)
  288. }
  289. void DefaultActivate(Ptr globals)
  290. {
  291. #pragma unused (globals)
  292. }
  293. void DefaultDeactivate(Ptr globals)
  294. {
  295. #pragma unused (globals)
  296. }
  297. void DefaultLoopy(Ptr globals)
  298. {
  299. #pragma unused (globals)
  300. }
  301. void pnull(void) {}
  302.  
  303. /************************************
  304. * Menu Action Routines
  305. ************************************/
  306.  
  307. //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  308. void MenuPoint(long theclick)
  309.   {
  310.   short mID,mItem;
  311.   unsigned char DAname[30];
  312.  
  313.   mID = HiWrd(theclick);
  314.   mItem = LoWrd(theclick);
  315.   
  316.   gLastMenuSelect = theclick;            /* save for others to look at */
  317.      
  318.   if(mID == 0)
  319.       return;
  320.  
  321.   if(mID == 1)                            /* Apple menu */
  322.     {
  323.     if(mItem == 1)                        /* Its either the about box */
  324.       DoMyAbout();
  325.     else
  326.       {                                    /* Or a DA */
  327.       GetItem(MenuHandleList[1],mItem,DAname);
  328.       OpenDeskAcc(DAname);
  329.       }
  330.     }
  331.   else
  332.     (*MenuProcs[mID][mItem-1])();
  333.  
  334.   HiliteMenu(0);
  335.   }
  336.  
  337. //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  338. void DoKeyPress(long k)
  339.   {
  340.   MenuPoint(MenuKey((char)k));
  341.   }
  342.  
  343. //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  344. void MenuClick(Point p)
  345.   {
  346.   MenuPoint(MenuSelect(p));
  347.   }
  348.  
  349. //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  350. // Start with just an About box, and some DA's.
  351.  
  352. void StartMenus(void)
  353. {
  354.   MenuHandle applemenu;
  355.   applemenu = NewMenu(1,"\p");                /* Apple menu: ID 1 */
  356.   AppendMenu(applemenu,"\pAbout...;(-");
  357.   AddResMenu(applemenu,'DRVR');
  358.   InsertMenu(applemenu,0);
  359.   DrawMenuBar();
  360.   MenuHandleList[1] = applemenu;
  361.  
  362.   MenuCount = 1;                            /* Next menu added will be ID 2 */
  363.  }
  364.  
  365. //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  366. void InstallMenu(Str255 s)
  367. /*
  368.  * Start a new menu with name s
  369.  */
  370.   {
  371.   MenuCount++;                                /* new menu */
  372.   MenuItemCount = 0;                        /* with no entries */
  373.  
  374.   MenuHandleList[MenuCount] = NewMenu(MenuCount,s);
  375.   InsertMenu(MenuHandleList[MenuCount],0);
  376.   DrawMenuBar();
  377.   }
  378.  
  379. //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  380. void InstallItem(Str255 s, IFP action)
  381. /*
  382.  * Add an item to the last menu, and associate a routine with it.
  383.  */
  384.   {
  385.   if (MenuItemCount < MIMax) {
  386.       AppendMenu(MenuHandleList[MenuCount],s);
  387.       MenuProcs[MenuCount][MenuItemCount++] = action;
  388.   }
  389.   else
  390.       SysBeep(10);
  391.   }
  392.  
  393. //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  394. void InstallEditMenu(IFP Xundo,IFP Xcut,IFP Xcopy,IFP Xpaste,IFP Xclear)
  395. /*
  396.  * Start an edit menu, and put the first six things in.
  397.  */
  398.   {
  399.   AppUndo = Xundo;
  400.   AppCut = Xcut;
  401.   AppCopy = Xcopy;
  402.   AppPaste = Xpaste;
  403.   AppClear = Xclear;
  404.  
  405.   InstallMenu("\pEdit");
  406.   InstallItem("\pUndo/Z",BEUndo);
  407.   InstallItem("\p(-",BENull);
  408.   InstallItem("\pCut/X",BECut);
  409.   InstallItem("\pCopy/C",BECopy);
  410.   InstallItem("\pPaste/V",BEPaste);
  411.   InstallItem("\pClear/B",BEClear);
  412.  
  413.   MenuEdit = MenuHandleList[MenuCount];
  414.   }
  415.  
  416. //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  417. // Enable or disable any given menu item.
  418. void EnableMenu(MenuHandle menu, short item, Boolean enable)
  419. {
  420.   if (enable)
  421.     EnableItem(menu,item);
  422.   else
  423.     DisableItem(menu,item);
  424.  }
  425.  
  426. //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  427. void EnDis(MenuHandle m, short i, short f)
  428. /*
  429.  * Enable or disable item i of menu m.
  430.  */
  431.   {
  432.   if (f==0)
  433.     DisableItem(m,i);
  434.   else if (f > 0)
  435.     EnableItem(m,i);
  436.   }
  437.  
  438. //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  439. void EnDisEdits(short Eundo,short Ecut,short Ecopy,short Epaste,short Eclear)
  440. /*
  441.  * For each edit menu entry,
  442.  * 0=disable, 1=enable, -1=leave alone.
  443.  */
  444.   {
  445.   EnDis(MenuEdit,1,Eundo);
  446.   EnDis(MenuEdit,3,Ecut);
  447.   EnDis(MenuEdit,4,Ecopy);
  448.   EnDis(MenuEdit,5,Epaste);
  449.   EnDis(MenuEdit,6,Eclear);
  450.   }
  451.  
  452.  
  453. /************************************
  454. * Mouse Action Routines
  455. ************************************/
  456.  
  457. //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  458. void DoMouseClick(EventRecord *event)
  459.   {
  460.   WindowPtr            w;
  461.   WindowObjectPtr    wo;
  462.   short                part;
  463.   short                i;
  464.  
  465.   part = FindWindow (event->where, &w);
  466.  
  467.   switch (part)
  468.     {
  469.     case inDesk:        /* click on desk */
  470.       break;
  471.  
  472.     case inMenuBar:        /* menubar */
  473.       MenuClick(event->where);
  474.       break;
  475.  
  476.     case inSysWindow:        /* system window */
  477.       SystemClick(event,w);
  478.       break;
  479.  
  480.     case inContent:        /* content region */
  481.  
  482.       if (w != FrontWindow())                            /* If clicked on a non-front window, */
  483.         SelectWindow(w);                                /* bring it to the front. */
  484.       else if (wo = ScanWindowObjectList(w, &i))        /* Click on front window: give click */
  485.         {                                                /* to window's click routine. */
  486.         SetPort(w);
  487.         (*wo->wClick)(wo->wGlobals, event->where, event->modifiers, event->when);
  488.         }
  489.       break;
  490.  
  491.     case inGrow:        /* growregion */
  492.       SetPort(w);
  493.       DoGrowWindow(w, event);
  494.       break;
  495.     
  496.     case inDrag:        /* drag */
  497.       DragWindow (w,event->where,&bigRect);
  498.       break;
  499.  
  500.     case inGoAway:        /* goAway */
  501.       if (TrackGoAway(w,event->where))
  502.         if (wo = ScanWindowObjectList(w, &i))
  503.           (*wo->wClose)(wo->wGlobals);
  504.       break;
  505.     }
  506.   }
  507.  
  508. void DoGrowWindow( WindowPtr window, EventRecord *event )
  509. {
  510.     long    growResult;
  511.     Rect    tempRect;
  512.     
  513.     tempRect = qd.screenBits.bounds;                    /* set up limiting values */
  514.  
  515.     growResult = GrowWindow(window, event->where, &tempRect);
  516.  
  517.     /* see if it really changed size */
  518.  
  519.     if ( growResult != 0 ) 
  520.     {
  521.         SizeWindow(window, LoWrd(growResult), HiWrd(growResult), true);
  522.         ResizeWindow(window);
  523.         DrawGrowIcon(window);
  524.     }
  525. }
  526.  
  527. void DoZoomWindow( WindowPtr window, short part )
  528. {
  529.     EraseRect(&window->portRect);
  530.     ZoomWindow(window, part, window == FrontWindow());
  531.     ResizeWindow(window);
  532. }
  533.  
  534. void ResizeWindow( WindowPtr window )
  535. {
  536.     InvalRect(&window->portRect);
  537. }
  538.  
  539. void GetLocalUpdateRgn( WindowPtr window, RgnHandle localRgn ) /* Returns the update region in local coordinates */
  540. {
  541.     CopyRgn(((WindowPeek) window)->updateRgn, localRgn);    /* save old update region */
  542.     OffsetRgn(localRgn, window->portBits.bounds.left, window->portBits.bounds.top);
  543. }
  544.  
  545.  
  546. /************************************
  547. * Window Action Routines
  548. ************************************/
  549.  
  550. //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  551. Ptr InstallWindow(Rect *iRect, short iType, Boolean iGoway, unsigned char *iTitle,
  552.                   UpdateProc iUpdate, ClickProc iClick, GrowProc iGrow, KeyProc iKey,
  553.                   CloseProc iClose, DeathProc iDeath, ActivateProc iActivate, DeactivateProc iDeactive,
  554.                   LoopyProc iLoopy, long iGlobalsSize, WindowPtr *thisWindowPtr)
  555. /*
  556.  * Add a window to BigEasy's list. If the window is
  557.  * already up somewhere, bring it to the front and
  558.  * visualize it.
  559.  */
  560. {
  561. #pragma unused (iGrow)
  562.  
  563.     WindowObject    *thisWindow;
  564.     Ptr                p = nil;
  565.  
  566.     if (*thisWindowPtr != 0)            /* something already assigned to this window? */
  567.     {
  568.         if(!((WindowPeek) *thisWindowPtr)->visible)    /* If so, just show it, and bring it to the front. */
  569.             ShowWindow(*thisWindowPtr);
  570.         SelectWindow(*thisWindowPtr);
  571.         return (nil);
  572.     }
  573.  
  574.       thisWindow = &WindowObjectList[WindowCount];
  575.  
  576.     if (HaveCQD())
  577.     {
  578.            p = NewPtrClear(sizeof(CWindowRecord) + iGlobalsSize);        /* make room for window record + globals */
  579.         if (p)
  580.             thisWindow->wWindow = NewCWindow(p, iRect, iTitle, true, iType, (WindowPtr) -1, iGoway, 0);
  581.     }
  582.     else
  583.     {
  584.            p = NewPtrClear(sizeof(WindowRecord) + iGlobalsSize);        /* make room for window record + globals */
  585.         if (p)
  586.             thisWindow->wWindow = NewWindow(p, iRect, iTitle, true, iType, (WindowPtr) -1, iGoway, 0);
  587.     }
  588.     
  589.     if (!thisWindow->wWindow)
  590.     {
  591.         DisposePtr(p);
  592.         return (nil);
  593.     }
  594.  
  595.     thisWindow->wUpdate = iUpdate;
  596.     thisWindow->wClick = iClick;
  597.     thisWindow->wKey = iKey;
  598.     thisWindow->wClose = iClose;
  599.     thisWindow->wDeath = iDeath;
  600.     thisWindow->wActivate = iActivate;
  601.     thisWindow->wDeactivate = iDeactive;
  602.     thisWindow->wLoopy = iLoopy;
  603.     if (HaveCQD())
  604.         thisWindow->wGlobals = p + sizeof(CWindowRecord);
  605.     else
  606.         thisWindow->wGlobals = p + sizeof(WindowRecord);
  607.  
  608.     WindowCount++;
  609.  
  610.     *thisWindowPtr = thisWindow->wWindow;
  611.     return (thisWindow->wGlobals);
  612. }
  613.  
  614. //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  615. Ptr GetInstallWindow(short windID,
  616.                   UpdateProc iUpdate, ClickProc iClick, GrowProc iGrow, KeyProc iKey,
  617.                   CloseProc iClose, DeathProc iDeath, ActivateProc iActivate, DeactivateProc iDeactive,
  618.                   LoopyProc iLoopy, long iGlobalsSize, WindowPtr *thisWindowPtr)
  619.  
  620. {
  621.     Ptr                result;
  622.     WindowTHndl        windTemplate;
  623.  
  624.     windTemplate = (WindowTHndl) GetResource('WIND', windID);
  625.     if (windTemplate == nil) {
  626.         Debugger();
  627.         return (nil);
  628.     }
  629.  
  630.     HLock((Handle)windTemplate);
  631.     result = InstallWindow(&((**windTemplate).boundsRect),
  632.                             (**windTemplate).procID,
  633.                             (**windTemplate).goAwayFlag,
  634.                             (**windTemplate).title,
  635.                             iUpdate, iClick, iGrow, iKey, iClose, iDeath, iActivate,
  636.                             iDeactive, iLoopy,
  637.                             iGlobalsSize, thisWindowPtr);
  638.     HUnlock ((Handle)windTemplate);
  639.     HPurge ((Handle)windTemplate);
  640.     return (result);
  641. }
  642.  
  643. //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  644. Ptr InstallDialog(short iResID, ClickProc iClick, CloseProc iClose, long iGlobalsSize, DialogPtr *thisWindowPtr)
  645. /*
  646.  * Add a dialog to BigEasy's list. If the window is
  647.  * already up somewhere, bring it to the front and
  648.  * visualize it.
  649.  */
  650.   {
  651.     WindowObject    *thisWindow;
  652.     Ptr                p;
  653.  
  654.     if (*thisWindowPtr != 0)            /* something already assigned to this window? */
  655.     {
  656.         if(!((WindowPeek) *thisWindowPtr)->visible)    /* If so, just show it, and bring it to the front. */
  657.             ShowWindow((WindowPtr) *thisWindowPtr);
  658.         SelectWindow((WindowPtr) *thisWindowPtr);
  659.         return (nil);
  660.     }
  661.  
  662.  
  663.     thisWindow = &WindowObjectList[WindowCount];
  664.  
  665.        p = NewPtrClear(sizeof(DialogRecord) + iGlobalsSize);        /* make room for window record + globals */
  666.  
  667.     thisWindow->wWindow = GetNewDialog(iResID, p, (WindowPtr) -1);
  668.     if (!thisWindow->wWindow)
  669.     {
  670.         DisposePtr(p);
  671.         return (nil);
  672.     }
  673.  
  674.     thisWindow->wUpdate = (UpdateProc) DefaultUpdate;
  675.     thisWindow->wClick = iClick;
  676.     thisWindow->wKey = DefaultKey;
  677.     thisWindow->wClose = iClose;
  678.     thisWindow->wActivate = DefaultActivate;
  679.     thisWindow->wDeactivate = DefaultDeactivate;
  680.     thisWindow->wLoopy = DefaultLoopy;
  681.     thisWindow->wGlobals = p + sizeof(DialogRecord);
  682.  
  683.     WindowCount++;
  684.  
  685.     *thisWindowPtr = (DialogPtr) thisWindow->wWindow;
  686.     return (thisWindow->wGlobals);
  687.   }
  688.  
  689. //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  690. void UninstallWindow(WindowPtr uWindow)
  691. {
  692.     short i;
  693.  
  694.     if (ScanWindowObjectList(uWindow, &i))
  695.     {
  696.         CloseWindow(uWindow);
  697.         DisposePtr((Ptr) uWindow);
  698.         WindowObjectList[i] = WindowObjectList[--WindowCount];
  699.     }
  700. }
  701.  
  702. //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  703. void UninstallDialog(DialogPtr uDialog)
  704. {
  705.     short i;
  706.  
  707.     if (ScanWindowObjectList(uDialog, &i))
  708.     {
  709.         CloseDialog(uDialog);
  710.         DisposePtr((Ptr) uDialog);
  711.         WindowObjectList[i] = WindowObjectList[--WindowCount];
  712.     }
  713. }
  714.  
  715. //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  716. void DoCloseWindow(void)
  717. {
  718.     WindowPtr        w;
  719.     WindowObjectPtr    wo;
  720.     short            i;
  721.  
  722.     w = FrontWindow();
  723.     if (wo = ScanWindowObjectList(w, &i))
  724.     {
  725.         SetPort(w);
  726.         (*wo->wClose)(wo->wGlobals);
  727.     }
  728. }
  729.  
  730. //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  731. void DoQuit(void)
  732. {
  733.     short            i;
  734.     WindowObjectPtr    wo;
  735.  
  736.     wo = WindowObjectList;
  737.     i = WindowCount;
  738.     while (i)
  739.     {
  740.         SetPort(wo->wWindow);
  741.         (*wo->wClose)(wo->wGlobals);
  742.         --i;
  743.     }
  744.  
  745.     gQuitApp = true;
  746. }
  747.  
  748. //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  749. WindowObjectPtr ScanWindowObjectList(WindowPtr w, short *n)
  750. /*
  751.  * Set n to the window number of w, if its there. Return TRUE if
  752.  * the window was found, or FALSE if not.
  753.  */
  754. {
  755.     short i;
  756.  
  757.     for (i = 0; i < WindowCount; i++)
  758.         if (WindowObjectList[i].wWindow == w)
  759.         {
  760.             *n = i;
  761.             return (&WindowObjectList[i]);
  762.         }
  763.  
  764.     return (nil);
  765. }
  766.  
  767. //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  768. Ptr GetWindowStorage(WindowPtr w)
  769. {
  770.     WindowObjectPtr    wo;
  771.     short            n;
  772.     
  773.     if (wo = ScanWindowObjectList(w, &n))
  774.         return (wo->wGlobals);
  775.     else 
  776.         return (nil);
  777. }
  778.  
  779. //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  780. void FrontDA(void)
  781. /*
  782.  * Check the front window. If it's a DA,
  783.  * enable all edit menu options.
  784.  */
  785.   {
  786.   WindowPeek     window;
  787.  
  788.   window = (WindowPeek)FrontWindow();
  789.   if (window->windowKind < 0)                    /* Any click in a DA window: */
  790.     EnDisEdits(1,1,1,1,1);                        /* enable edit menu. */
  791.   }
  792.  
  793. /************************************
  794. * Event Routines
  795. ************************************/
  796.  
  797. //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  798. GrafPtr    SaveGrafPort(GrafPtr newPort)
  799. {
  800.     GrafPtr    oldPort;
  801.  
  802.     GetPort(&oldPort);
  803.     SetPort(newPort);
  804.     return (oldPort);
  805. }
  806.  
  807. //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  808. void EventLoop(void)
  809. {
  810.     EventRecord        ER;
  811.     short            i;
  812.     WindowPtr        w;
  813.     WindowObjectPtr    wo;
  814.     short            item;
  815.     GrafPtr            oldPort;
  816.  
  817.     SetCursor(&qd.arrow);            // make sure our cursor is the arrow
  818.  
  819.     if ( WaitNextEvent(everyEvent, &ER, kStandardSleep, nil) ) {
  820.  
  821.         if (IsDialogEvent(&ER)) {
  822.             if (DialogSelect(&ER, &w, &item)) {
  823.                 if (wo = ScanWindowObjectList(w,&i)) {
  824.                      oldPort = SaveGrafPort(wo->wWindow);
  825.                     (*wo->wClick)(wo->wGlobals, ER.where, item, ER.when);
  826.                      SaveGrafPort(oldPort);
  827.                      return;
  828.                 }
  829.             }
  830.          }
  831.     }
  832.     else {
  833.  
  834.         // nullEvents come in here only when WaitNextEvent returns false
  835.         // this happens when the sleep time has expired
  836.         wo = WindowObjectList;
  837.         for (i = 0; i < WindowCount; i++) {
  838.             (*wo->wLoopy)(wo->wGlobals);
  839.             wo++;
  840.         }
  841.  
  842.         if (IsDialogEvent(&ER))
  843.             DialogSelect(&ER, &w, &item);
  844.         return;
  845.     }
  846.  
  847.     switch (ER.what)
  848.     {
  849.         case mouseDown:        /* mouse down */
  850.             FrontDA();
  851.               DoMouseClick(&ER);
  852.             break;
  853.  
  854.         case keyDown:            /* key event */
  855.         case autoKey:
  856.             FrontDA();
  857.             DoKeyPress(ER.message);
  858.             if (wo = ScanWindowObjectList(FrontWindow(), &i))
  859.                 (*wo->wKey)(wo->wGlobals, ER.message, ER.modifiers);
  860.             break;
  861.  
  862.         case updateEvt:        /* update */
  863.             if (wo = ScanWindowObjectList((WindowPtr) ER.message, &i))
  864.             {
  865.                 BeginUpdate((WindowPtr) ER.message);
  866.                 SetPort((WindowPtr) ER.message);
  867.                 (*wo->wUpdate)(wo->wGlobals);
  868.                 EndUpdate((WindowPtr) ER.message);
  869.             }
  870.             break;
  871.  
  872.         case activateEvt:        /* activate */
  873.             FrontDA();
  874.             if (wo = ScanWindowObjectList((WindowPtr) ER.message, &i))
  875.             {
  876.                 oldPort = SaveGrafPort(wo->wWindow);
  877.                 if (ER.modifiers & activeFlag)
  878.                     (*wo->wActivate)(wo->wGlobals);
  879.                 else
  880.                     (*wo->wDeactivate)(wo->wGlobals);
  881.                 DrawGrowIcon(wo->wWindow);
  882.                 SaveGrafPort(oldPort);
  883.             }
  884.             break;
  885.     }
  886. }
  887.  
  888. //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  889. void DoNew(void)
  890. {
  891. }
  892.  
  893. //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  894. void DoOpen(void)
  895. {
  896. }
  897.  
  898. //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  899. void DoClose(Ptr storage)
  900. {
  901. #pragma unused (storage)
  902.  
  903.     UninstallWindow(FrontWindow());
  904. }
  905.  
  906. //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  907. void main(void)
  908. {
  909.     InitToolbox();
  910.     StartMenus();
  911.  
  912.     Bootstrap();                    // start things going
  913.  
  914.     while (!gQuitApp)
  915.         EventLoop();
  916. }
  917.